home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / iutil / find.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-01-23  |  3.7 KB  |  201 lines

  1. # include    <ingres.h>
  2. # include    <aux.h>
  3. # include    <symbol.h>
  4. # include    <access.h>
  5. # include    <lock.h>
  6. # include    <btree.h>
  7. # include    <sccs.h>
  8.  
  9. SCCSID(@(#)find.c    8.1    12/31/84)
  10.  
  11.  
  12. /*
  13. **    Find - determine limits for scan of a relation
  14. **
  15. **    Find determines the values of an initial TID
  16. **    and an ending TID for scanning a relation.
  17. **    The possible calls to find are:
  18. **
  19. **    find(desc, NOKEY, lotid, hightid)
  20. **        sets tids to scan entire relation
  21. **
  22. **    find(desc, EXACTKEY, lotid, hightid, key)
  23. **        sets tids according to structure
  24. **        of the relation. Key should have
  25. **        been build using setkey.
  26. **
  27. **    find(desc, LRANGEKEY, lotid, hightid, keylow)
  28. **        Finds lotid less then or equal to keylow
  29. **        for isam relations. Otherwise scans whole relation.
  30. **        This call should be followed by a call with HRANGEKEY.
  31. **
  32. **    find(desc, HRANGEKEY, lotid, hightid, keyhigh)
  33. **        Finds hightid greater than or equal to
  34. **        keyhigh for isam relations. Otherwise sets
  35. **        hightid to maximum scan.
  36. **
  37. **    find(desc, FULLKEY, lotid, hightid, key)
  38. **        Same as find with EXACTKEY and all keys
  39. **        provided. This mode is used only by findbest
  40. **        and replace.
  41. **
  42. **    returns:
  43. **        <0 fatal error
  44. **         0 success
  45. **
  46. **    Trace Flags:
  47. **        22.0-8
  48. */
  49.  
  50.  
  51. find(d, mode, lotid, hightid, key)
  52. register DESC    *d;
  53. int        mode;
  54. TID        *lotid;
  55. TID        *hightid;
  56. char        *key;
  57. {
  58.     register int    ret;
  59.     bool        keyok;
  60.     long        pageid, lid[MAXLID], page;
  61.     long        rhash(), get_tid();
  62.     struct locator  tid_id;
  63.     char        *tp;
  64.     int        i;
  65.     extern int    Btree_fd;
  66.  
  67. #    ifdef xATR1
  68.     if (tTf(22, 0))
  69.     {
  70.         printf("find: m%d,s%d,%.14s\n", mode, d->reldum.relspec, d->reldum.relid);
  71.         if (mode != NOKEY)
  72.             printup(d, key);
  73.     }
  74. #    endif
  75.  
  76.     ret = 0;    /* assume successful return */
  77.     keyok = FALSE;
  78.  
  79.     switch (mode)
  80.     {
  81.  
  82.       case EXACTKEY:
  83.         keyok = fullkey(d);
  84.         break;
  85.  
  86.       case FULLKEY:
  87.         keyok = TRUE;
  88.  
  89.       case NOKEY:
  90.       case LRANGEKEY:
  91.       case HRANGEKEY:
  92.       case BTREEKEY:
  93.         break;
  94.  
  95.       default:
  96.         syserr("FIND: bad mode %d", mode);
  97.     }
  98.  
  99.     /* set lotid for beginning of scan */
  100.     if (mode != HRANGEKEY)
  101.     {
  102.         pageid = 0;
  103.         stuff_page(lotid, &pageid);
  104.         lotid->line_id = -1;
  105.     }
  106.  
  107.     /* set hitid for end of scan */
  108.     if (mode != LRANGEKEY)
  109.     {
  110.         pageid = -1;
  111.         stuff_page(hightid, &pageid);
  112.         hightid->line_id = -1;
  113.     }
  114.  
  115.     if (mode == BTREEKEY)
  116.     /* set tid to value as found using B-Tree */
  117.     {
  118.         tp = key + d->reldum.relwid - LIDSIZE * d->reldum.reldim;
  119.         bmove(tp, lid, LIDSIZE * d->reldum.reldim);
  120.         Btree_fd = d->btree_fd;
  121.         page = RT;
  122.         for (i = 0; i < d->reldum.reldim; ++i)
  123.         {
  124.             pageid = get_tid(page, lid[i], &tid_id);
  125.             if (pageid < 0)
  126.                 break;
  127.             page = pageid;
  128.         }
  129.         if (pageid >= 0)
  130.             bmove(&pageid, lotid, LIDSIZE);
  131.  
  132.     }
  133.     else if (mode != NOKEY)
  134.     {
  135.         switch (abs(d->reldum.relspec))
  136.         {
  137.     
  138.           case M_HEAP:
  139.             break;
  140.     
  141.           case M_ISAM:
  142.             if (mode != HRANGEKEY)
  143.             {
  144.                 /* compute lo limit */
  145.                 if (ret = ndxsearch(d, lotid, key, -1, keyok))
  146.                     break;    /* fatal error */
  147.             }
  148.     
  149.             /* if the full key was provided and mode is exact, then done */
  150.             if (keyok)
  151.             {
  152.                 bmove((char *) lotid, (char *) hightid, sizeof *lotid);
  153.                 break;
  154.             }
  155.     
  156.             if (mode != LRANGEKEY)
  157.                 ret = ndxsearch(d, hightid, key, 1, keyok);
  158.             break;
  159.     
  160.           case M_HASH:
  161.             if (!keyok)
  162.                 break;        /* can't do anything */
  163.             pageid = rhash(d, key);
  164.             stuff_page(lotid, &pageid);
  165.             stuff_page(hightid, &pageid);
  166.             break;
  167.  
  168.           default:
  169.             ret = acc_err(AMFIND_ERR);
  170.         }
  171.     }
  172.  
  173. #    ifdef xATR2
  174.     if (tTf(22, 1))
  175.     {
  176.         printf("find: ret %d\tlow", ret);
  177.         dumptid(lotid);
  178.         printf("hi");
  179.         dumptid(hightid);
  180.     }
  181. #    endif
  182.     return (ret);
  183. }
  184. /*
  185. ** This routine will check that enough of the tuple has been specified
  186. ** to enable a key access.
  187. */
  188.  
  189. fullkey(des)
  190. DESC    *des;
  191. {
  192.     register DESC    *d;
  193.     register int    i;
  194.  
  195.     d = des;
  196.     for (i = 1; i <= d->reldum.relatts; i++)
  197.         if (d->relxtra[i] && !d->relgiven[i])
  198.             return (FALSE);
  199.     return (TRUE);
  200. }
  201.